package com.king.juc.fivetest;

import java.io.Serializable;

/**
 * 线程安全单例习题
 * 单例模式有很多实现方法, 懒汉, 饿汉, 静态内部类, 枚举类, 试分析每种实现下获取单例对象(即调用getInstance)时的线程安全, 并思考注释中的问题
 * 饿汉式: 类加载就会导致该实例对象被创建
 * 懒汉式: 类加载不会导致该单实例对象被创建, 而是首次使用该对象时才会创建
 *
 * 案例1
 * @author king
 * @date 2020/11/28 20:23
 */
public final class SingletonOne implements Serializable {
    // 问题1: 为什么加final
    // 答: 怕有子类覆盖, 破坏单例

    // 问题2: 如果是想了序列化接口, 还要做什么来防止反序列化破坏单例
    // 答: 实现 readResovle() 方法, 在反序列化中当检测到你返回了一个对象, 就会使用该对象
    public Object readResovle() {
        return INSTANCE;
    }

    // 问题3: 为什么设置为私有? 是否能防止反射创建新的实例?
    // 答: 公有的可以由别的类无限创建, 不存在单例对象. 不能防止反射来创建新的实例.
    private SingletonOne() {
    }

    // 问题4: 这样初始化是否能保证单例对象创建时的线程安全?
    // 答: 没有线程安全问题
    private static final SingletonOne INSTANCE = new SingletonOne();

    // 问题5: 为什么提供静态方法而不是直接将INSTANCE设置为public, 说出你知道的原因
    // 答: 提供更好的封装性, 可以实现一些懒惰的触发, 可以有更多的控制, 提供泛型支持
    public static SingletonOne getInstance() {
        return INSTANCE;
    }
}
